Skip to main content

Chat Consultation

ChatConfig Object

For chat consultations, the consultation data will include the ChatConfig object. This config data will be used to initiate and handle the chat between the user and the doctor.

interface ChatConfig {
id?: number;
consultation_id?: number;
group_id?: string;
chat_user_id?: string;
app_id?: string;
chat_user_token?: string;
}

Initiating the Chat Service

First the chat service should be initiated using the AltibbiChat.init() method with the app_id from the ChatConfig object and an instance of GroupChannelModule.

import {
AltibbiChat,
ConnectionHandler,
GroupChannelHandler,
GroupChannelModule,
uploadMedia,
GroupChannel,
} from 'react-native-altibbi';

const chatServiceInstance = AltibbiChat.init({
appId: data.app_id,
modules: [new GroupChannelModule()],
});

Adding Event Listeners and Handlers

You have to add some handler functions to the chatService channel, and there are two types of handlers: GroupChannelHandler and ConnectionHandler.

Check the code below to see how the handlers should be declared and added to the chatService channel.

ConnectionHandlers

const onConnected = () => {/*Connected*/};
const onReconnectStarted = () => {/*ReconnectStarted*/};
const onReconnectSucceeded = () => {/*ReconnectSucceeded*/};
const onReconnectFailed = () => {/*ReconnectFailed*/};
const onDisconnected = () => {/*Disconnected*/};

const connectionHandler = new ConnectionHandler({
onConnected,
onReconnectStarted,
onReconnectSucceeded,
onReconnectFailed,
onDisconnected,
});

chatServiceInstance.addConnectionHandler('CHA_CONN', connectionHandler);

GroupChannelHandlers

const onUserJoined = () => {/*UserJoined*/};
const onUserLeft = () => {/*UserLeft*/};
const onTypingStatusUpdated = (groupChannel) => {
/** You can use this listener to indicate that the other side is typing */
const members = groupChannel.getTypingUsers();
// Check if the members array contains the other member of the chat to indicate or view typing status
};

const onMessageReceived = (channel, message) => {
/** Handle adding the received message to the messages list */
/**
The Message Structure
{
createdAt: message.createdAt,
message: message.message,
messageId: message.messageId,
sender: message.sender.userId,
}
*/
};

const groupChannelHandler = new GroupChannelHandler({
onUserJoined,
onUserLeft,
onTypingStatusUpdated,
onMessageReceived,
});

chatServiceInstance.groupChannel.addGroupChannelHandler(
'CHA_HAN',
groupChannelHandler
);

Connecting The ChatService

After initiating the chat service and adding the handlers, the chat service should be connected.

From the ChatConfig data you need to use chat_user_id and chat_user_token when connecting the service.

await chatServiceInstance.connect(data.chat_user_id, data.chat_user_token);

Loading All Channel Messages

After connecting the ChatService or when re-entering the chat screen, you need to load the previous messages of the channel.

From the ChatConfig data, the group_id represents the channel identifier which is needed to load the previous messages.

// The channelUrl is the combination of 'channel_' with the group_id
const channelUrl = `channel_${data.group_id}`;
const channel = await chatServiceInstance.groupChannel.getChannel(channelUrl);
const previousMessageListQuery = channel.createPreviousMessageListQuery();
let allMessages = [];

while (previousMessageListQuery.hasNext) {
const newMsgArr = await previousMessageListQuery.load();
allMessages = [...allMessages, ...newMsgArr];
}

/** Now allMessages array represents all the messages in the channel */

Sending Messages

Now the chatService is initiated, connected and started. You can start sending messages using sendUserMessage from the channel instance with the message object that includes a message attribute.

const textMsg = "Message example";

channel.sendUserMessage({
message: textMsg,
}).onSucceeded((message) => {
/** Add the message to the messagesList state */
}).onFailed((error, message) => {
/** Handle the error by showing an alert or resend the message based on the error */
}).onPending(() => {
/** This could be used to show the message is being sent, also could be ignored */
});

Sending Media Files (Pictures or PDFs)

You can send pictures and PDF files on the chat using the previously mentioned uploadMedia functionality.

The process could be done by using uploadMedia, getting the url from the response, and sending it as a text message.

Send User Typing

You can register an event to indicate typing status by using startTyping() and endTyping().

const channelUrl = `channel_${data.group_id}`;
const channel = await chatServiceInstance.groupChannel.getChannel(channelUrl);

// When the user starts typing in the TextInput
channel.startTyping();
// When the user stops typing
channel.endTyping();

Render Messages

Rendering messages can be done using the React Native FlatList component. You can define the direction of messages according to chat_user_id from the ChatConfig data.

For images or PDF files you can check if the message includes cdn or pdf:

if (messageItem.message.includes('cdn')) {
// Render Image
} else if (messageItem.message.includes('pdf')) {
// Render PDF
} else {
// Render Text
}